#include "json.h"
#include "string.h"
#include <sstream>
#include <ctime>
#include <iomanip>
#include <cctype>

// 辅助函数：转义JSON中的特殊字符
std::string JsonUtils::escapeJson(const std::string& input) {
    std::string output;
    output.reserve(input.length());
    
    for (char c : input) {
        switch (c) {
            case '"':  output += "\\\""; break;
            case '\\': output += "\\\\"; break;
            case '\b': output += "\\b";  break;
            case '\f': output += "\\f";  break;
            case '\n': output += "\\n";  break;
            case '\r': output += "\\r";  break;
            case '\t': output += "\\t";  break;
            default:
                if (static_cast<unsigned char>(c) < 0x20) {
                    // 控制字符，用Unicode转义
                    output += "\\u" + std::string(2 - std::to_string(c).length(), '0') + std::to_string(c);
                } else {
                    output += c;
                }
        }
    }
    
    return output;
}

// 将资产对象序列化为JSON字符串
std::string JsonUtils::serializeAsset(const Asset& asset) {
    std::ostringstream oss;
    oss << "{";
    
    oss << "\"id\":" << asset.id << ",";
    oss << "\"name\":\"" << escapeJson(asset.name) << "\",";
    oss << "\"type\":\"" << escapeJson(asset.type) << "\",";
    oss << "\"description\":\"" << escapeJson(asset.description) << "\",";
    oss << "\"location\":\"" << escapeJson(asset.location) << "\",";
    oss << "\"value\":" << std::fixed << std::setprecision(2) << asset.value << ",";
    
    // 格式化时间
    if (asset.purchaseDate > 0) {
        std::time_t t = asset.purchaseDate;
        std::tm* tm = std::localtime(&t);
        oss << "\"purchaseDate\":\"" 
            << std::put_time(tm, "%Y-%m-%d") 
            << "\",";
    } else {
        oss << "\"purchaseDate\":null,";
    }
    
    oss << "\"status\":\"" << escapeJson(asset.status) << "\"";
    
    oss << "}";
    return oss.str();
}

// 将资产列表序列化为JSON字符串
std::string JsonUtils::serializeAssets(const std::vector<Asset>& assets) {
    std::ostringstream oss;
    oss << "[";
    
    for (size_t i = 0; i < assets.size(); ++i) {
        oss << serializeAsset(assets[i]);
        if (i != assets.size() - 1) {
            oss << ",";
        }
    }
    
    oss << "]";
    return oss.str();
}

// 辅助函数：解析键值对
bool JsonUtils::parseKeyValue(const std::string& json, size_t& pos, 
                             std::string& key, std::string& value) {
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    if (pos >= json.size() || json[pos] != '"') {
        return false; // 键应该以双引号开始
    }
    
    // 解析键
    pos++; // 跳过开头的双引号
    size_t keyStart = pos;
    while (pos < json.size() && json[pos] != '"') {
        // 处理转义字符
        if (json[pos] == '\\' && pos + 1 < json.size()) {
            pos++; // 跳过转义字符
        }
        pos++;
    }
    
    if (pos >= json.size() || json[pos] != '"') {
        return false; // 键应该以双引号结束
    }
    
    key = json.substr(keyStart, pos - keyStart);
    pos++; // 跳过结尾的双引号
    
    // 寻找冒号
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    if (pos >= json.size() || json[pos] != ':') {
        return false; // 应该有冒号分隔键和值
    }
    
    pos++; // 跳过冒号
    
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    // 解析值
    if (pos >= json.size()) {
        return false;
    }
    
    size_t valueStart = pos;
    
    if (json[pos] == '"') {
        // 字符串值
        pos++; // 跳过开头的双引号
        while (pos < json.size() && json[pos] != '"') {
            // 处理转义字符
            if (json[pos] == '\\' && pos + 1 < json.size()) {
                pos++; // 跳过转义字符
            }
            pos++;
        }
        
        if (pos >= json.size() || json[pos] != '"') {
            return false; // 字符串值应该以双引号结束
        }
        
        value = json.substr(valueStart + 1, pos - valueStart - 1);
        pos++; // 跳过结尾的双引号
    } else if (json[pos] == '{' || json[pos] == '[') {
        // 对象或数组，这里简化处理，只读取到对应的闭合符号
        char closingChar = (json[pos] == '{') ? '}' : ']';
        int depth = 1;
        pos++;
        
        while (pos < json.size() && depth > 0) {
            if (json[pos] == json[pos - 1] && json[pos - 1] == '\\') {
                // 跳过转义的字符
                pos++;
                continue;
            }
            
            if (json[pos] == json[pos - 1]) {
                // 处理引号内的内容
                pos++;
                continue;
            }
            
            if (json[pos] == closingChar) {
                depth--;
            } else if (json[pos] == (closingChar == '}' ? '{' : '[')) {
                depth++;
            }
            
            pos++;
        }
        
        value = json.substr(valueStart, pos - valueStart);
    } else if (json.compare(pos, 4, "true") == 0) {
        // 布尔值 true
        value = "true";
        pos += 4;
    } else if (json.compare(pos, 5, "false") == 0) {
        // 布尔值 false
        value = "false";
        pos += 5;
    } else if (json.compare(pos, 4, "null") == 0) {
        // null 值
        value = "null";
        pos += 4;
    } else {
        // 数字
        while (pos < json.size() && 
               (std::isdigit(static_cast<unsigned char>(json[pos])) || 
                json[pos] == '.' || json[pos] == '+' || json[pos] == '-' || 
                json[pos] == 'e' || json[pos] == 'E')) {
            pos++;
        }
        
        value = json.substr(valueStart, pos - valueStart);
    }
    
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    // 检查是否有逗号，如果有则跳过
    if (pos < json.size() && json[pos] == ',') {
        pos++;
        // 跳过逗号后的空白字符
        while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
            pos++;
        }
    }
    
    return true;
}

// 将JSON字符串解析为资产对象
Asset JsonUtils::parseAsset(const std::string& json) {
    Asset asset;
    size_t pos = 0;
    
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    // 检查是否以{开头
    if (pos >= json.size() || json[pos] != '{') {
        return asset;
    }
    
    pos++; // 跳过{
    
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    // 解析键值对
    while (pos < json.size() && json[pos] != '}') {
        std::string key, value;
        if (!parseKeyValue(json, pos, key, value)) {
            break;
        }
        
        // 处理各个字段
        if (key == "id") {
            try {
                asset.id = std::stoi(value);
            } catch (...) {
                // 忽略解析错误
            }
        } else if (key == "name") {
            asset.name = value;
        } else if (key == "type") {
            asset.type = value;
        } else if (key == "description") {
            asset.description = value;
        } else if (key == "location") {
            asset.location = value;
        } else if (key == "value") {
            try {
                asset.value = std::stod(value);
            } catch (...) {
                // 忽略解析错误
            }
        } else if (key == "purchaseDate" && value != "null") {
            // 解析日期 (YYYY-MM-DD)
            std::tm tm = {};
            std::istringstream ss(value);
            ss >> std::get_time(&tm, "%Y-%m-%d");
            if (!ss.fail()) {
                asset.purchaseDate = std::mktime(&tm);
            }
        } else if (key == "status") {
            asset.status = value;
        }
    }
    
    return asset;
}

// 将JSON字符串解析为资产列表
std::vector<Asset> JsonUtils::parseAssets(const std::string& json) {
    std::vector<Asset> assets;
    size_t pos = 0;
    
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    // 检查是否以[开头
    if (pos >= json.size() || json[pos] != '[') {
        return assets;
    }
    
    pos++; // 跳过[
    
    // 跳过空白字符
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        pos++;
    }
    
    // 解析每个资产对象
    while (pos < json.size() && json[pos] != ']') {
        // 查找对象的结束位置
        if (pos >= json.size() || json[pos] != '{') {
            break;
        }
        
        size_t objStart = pos;
        int braceCount = 1;
        pos++;
        
        while (pos < json.size() && braceCount > 0) {
            if (json[pos] == '{') {
                braceCount++;
            } else if (json[pos] == '}') {
                braceCount--;
            }
            pos++;
        }
        
        if (braceCount == 0) {
            std::string objJson = json.substr(objStart, pos - objStart);
            Asset asset = parseAsset(objJson);
            assets.push_back(asset);
        }
        
        // 跳过空白字符
        while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
            pos++;
        }
        
        // 跳过逗号
        if (pos < json.size() && json[pos] == ',') {
            pos++;
            // 跳过逗号后的空白字符
            while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
                pos++;
            }
        }
    }
    
    return assets;
}
